------------------------------------------
-- 进度奖励

-- [aimID] = {[rank] = {uuid, time}}
-- db.billboardAim[aimID] = 是否领取
------------------------------------------

local BillboardExcel = require("excel.billboard")
local Util = require("common.Util")
local CommonDB = require("common.CommonDB")
local Lang = require("common.Lang")
local Msg = require("core.Msg")
local Broadcast = require("broadcast.Broadcast")
local Grid = require("bag.Grid")
local BagLogic = require("bag.BagLogic")
local BillboardDefine = require("billboard.BillboardDefine")
local BattleLogic = require("battle.BattleLogic")
local RoleLogic = require("role.RoleLogic")
local BillboardLogic = require("billboard.BillboardLogic")
local RoleSystemLogic = require("roleSystem.RoleSystemLogic")
local RoleSystemDefine = require("roleSystem.RoleSystemDefine")

local AIM_LOG_MAX_CNT = 5 		-- 达标最多记录x条

local STATUS_CANTGET = 0 		-- 不可领
local STATUS_CANGET = 1 		-- 可领
local STATUS_HADGET = 2 		-- 已领

-- 获取达标信息
function getAimData(aimID)
	local data = CommonDB.getValueByKey(CommonDB.KEY_BILLBOARD_AIM)
	if not data then return end

	return data[aimID]
end

-- 获取达标玩家信息
function getAimRoleData(aimID, rank)
	local aimData = getAimData(aimID)
	if not aimData then return end

	return aimData[rank]
end

-- 是否在记录里
local function isOnAimLog(aimData, uuid)
	if not aimData then return end

	for _, roleAim in ipairs(aimData) do
		if roleAim.uuid == uuid then
			return true
		end
	end
end

-- 完成目标回调
local function onAimFinish(aimID, uuid)
	local data = CommonDB.getValueByKey(CommonDB.KEY_BILLBOARD_AIM)
	data = data or {}
	data[aimID] = data[aimID] or {}

	local aimData = data[aimID] 
	if #aimData >= AIM_LOG_MAX_CNT then
		return 
	end
	if isOnAimLog(aimData, uuid) then
		return 
	end

	local roleAim = {}
	roleAim.uuid = uuid
	roleAim.time = os.time()
	aimData[#aimData + 1] = roleAim
	CommonDB.updateValue(CommonDB.KEY_BILLBOARD_AIM, data)
end

-- 排行榜变化回调
function onCallback(boardType, db, value)
	local list = getAimIDsByType(boardType)
	if not list then return end

	for _, aimID in ipairs(list) do
		local config = BillboardExcel.aim[aimID]
		if config.value > value then
			break
		end
		onAimFinish(aimID, db._id)
	end
end

-- 是否领取奖励
function isGetReward(human, aimID)
	if not human.db.billboardAim then
		return
	end
	return human.db.billboardAim[aimID]
end

-- 设置领取奖励
function setGetReward(human, aimID)
	if not human.db.billboardAim then
		human.db.billboardAim = {}
	end
	human.db.billboardAim[aimID] = true
end

--------------------------------------- excel ----------------------------------------------

local BOARDTYPE_2_LIST = nil
function getAimIDsByType(boardType)
	if not BOARDTYPE_2_LIST then
		BOARDTYPE_2_LIST = {}
		for id, config in Util.pairsByKeys(BillboardExcel.aim) do
			if not BOARDTYPE_2_LIST[config.boardType] then
				BOARDTYPE_2_LIST[config.boardType] = {}
			end
			local len = #BOARDTYPE_2_LIST[config.boardType]
			BOARDTYPE_2_LIST[config.boardType][len + 1] = id
		end
	end 
	return BOARDTYPE_2_LIST[boardType]
end

--------------------------------------- msg ------------------------------------------------

local function getAimStatus(human, aimID)
	local config = BillboardExcel.aim[aimID]
	if not config then
		return STATUS_CANTGET
	end
	if not getAimRoleData(aimID, 1) then
		return STATUS_CANTGET
	end
	if isGetReward(human, aimID) then
		return STATUS_HADGET
	end	
	return STATUS_CANGET
end

local function fontAimNet(net, aimID, human)
	local config = BillboardExcel.aim[aimID]
	net.id = aimID
	if config.boardType == BillboardDefine.TYPE_BATTLE then
		net.value = BattleLogic.getBattleName(config.value)
	else
		net.value = tostring(config.value)
	end
	net.roleBase[0] = 0
	local roleAim = getAimRoleData(aimID, 1)
	if roleAim then
		net.roleBase[0] = 1
		RoleLogic.getRoleBaseByUuid(roleAim.uuid, net.roleBase[1])
	end
	net.status = getAimStatus(human, aimID)
	Grid.makeItem(net.item, config.reward[1], config.reward[2])
end

function sendAimList(human, boardType)
	local config = BillboardExcel.board[boardType]
	if not config then
		return 
	end
	local list = getAimIDsByType(boardType)
	if not list then return end

	local msgRet = Msg.gc.GC_BILLBOARD_AIM_LIST
	msgRet.boardType = boardType
	msgRet.desc = config.aimDesc
	msgRet.list[0] = math.min(#msgRet.list, #list)
	for i = 1, msgRet.list[0] do
		local id = list[i]
		fontAimNet(msgRet.list[i], id, human)
	end
--	Msg.trace(msgRet)
	Msg.send(msgRet, human.fd)
end

local function fontAimRoleNet(net, rank, roleAim)
	net.rank = rank 
	RoleLogic.getRoleBaseByUuid(roleAim.uuid, net.roleBase)
	net.time = roleAim.time
end 

-- 查看前5达标的玩家列表
function sendAimDetial(human, aimID)
	local aimData = getAimData(aimID)
	local msgRet = Msg.gc.GC_BILLBOARD_AIM_DETAIL
	msgRet.id = aimID 
	msgRet.list[0] = aimData and #aimData or 0
	for i = 1, msgRet.list[0] do
		fontAimRoleNet(msgRet.list[i], i, aimData[i])
	end
--	Msg.trace(msgRet)
	Msg.send(msgRet, human.fd)
end

-- 领取奖励
function getAimReward(human, aimID)
	local status = getAimStatus(human, aimID)
	if status == STATUS_CANTGET then
		return Broadcast.sendErr(human, Lang.YUNYING_GET_ERR_CONDITION)
	end
	if status == STATUS_HADGET then
		return Broadcast.sendErr(human, Lang.YUNYING_GET_ERR_HADGET)
	end

	setGetReward(human, aimID)
	local config = BillboardExcel.aim[aimID]
	BagLogic.cleanMomentItemList()
	BagLogic.updateMomentItem(1, config.reward[1], config.reward[2])
	BagLogic.addMomentItemList(human, "billboard_aim")

	local msgRet = Msg.gc.GC_BILLBOARD_AIM_GET
	msgRet.id = aimID 
	Msg.send(msgRet, human.fd)

    BillboardLogic.sendMainList(human)
	RoleSystemLogic.onDot(human, RoleSystemDefine.ROLE_SYS_ID_203)
end

function isAimRed(human, boardType)
	local list = getAimIDsByType(boardType)
	if not list then return end
	for i = 1, #list do
		local aimID = list[i]
		local status = getAimStatus(human, aimID)
		if status == STATUS_CANTGET then
			break
		end
		if status == STATUS_CANGET then
			return true
		end
	end		
end